import React, { useEffect, useMemo } from 'react';
import { Background, NodeProps } from 'reactflow';
import { useContextSelector } from 'use-context-selector';

import FormLabel from '@/components/MyBox/FormLabel';
import { t } from '@/locales/i18n';
import { NodeInputKeyEnum } from '@/types/workflow/constant';
import { FlowNodeItemType } from '@/types/workflow/node';
import { Input_Template_Children_Node_List } from '@/types/workflow/template/input';

import { WorkflowContext } from '../../../context';
import Container from '../../flow/Container';
import IOTitle from '../../flow/IOTitle';
import NodeCard from '../render/NodeCard';
import RenderInput from '../render/RenderInput';
import RenderOutput from '../render/RenderOutput';

const NodeLoop = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
  const { nodeId, inputs, outputs, isFolded } = data;
  const { onChangeNode, nodeList } = useContextSelector(WorkflowContext, (v) => v);

  const { nodeWidth, nodeHeight } = useMemo(() => {
    return {
      nodeWidth: inputs.find((input) => input.key === NodeInputKeyEnum.nodeWidth)?.value,
      nodeHeight: inputs.find((input) => input.key === NodeInputKeyEnum.nodeHeight)?.value,
    };
  }, [inputs]);
  const childrenNodeIdList = useMemo(() => {
    return JSON.stringify(
      nodeList.filter((node) => node.parentNodeId === nodeId).map((node) => node.nodeId),
    );
  }, [nodeId, nodeList]);

  useEffect(() => {
    onChangeNode({
      nodeId,
      type: 'updateInput',
      key: NodeInputKeyEnum.childrenNodeIdList,
      value: {
        ...Input_Template_Children_Node_List,
        value: JSON.parse(childrenNodeIdList),
      },
    });
  }, [childrenNodeIdList, nodeId, onChangeNode]);

  const Render = useMemo(() => {
    return (
      <NodeCard
        selected={selected}
        maxW="full"
        {...(!isFolded
          ? {
              minW: '900px',
              minH: '900px',
              w: nodeWidth,
              h: nodeHeight,
            }
          : {
              minW: 'auto',
              minH: 'auto',
              w: '400px',
              h: 'auto',
            })}
        menuForbid={{ copy: true }}
        {...data}
      >
        <Container className="relative flex-1">
          <IOTitle text={t('common.Input')} />
          <div className="mb-5" style={{ maxWidth: '360px' }}>
            <RenderInput nodeId={nodeId} flowInputList={inputs} />
          </div>
          <FormLabel required className="mb-3 font-medium text-gray-600">
            {t('loop_body')}
          </FormLabel>
          <div
            className="relative flex-1 rounded-lg border-bgBase bg-gray-100"
            style={{ height: nodeHeight - 100 }}
          >
            <Background />
          </div>
        </Container>
        <div>
          <Container>
            <RenderOutput nodeId={nodeId} flowOutputList={outputs} />
          </Container>
        </div>
      </NodeCard>
    );
  }, [selected, isFolded, nodeWidth, nodeHeight, data, nodeId, inputs, outputs]);

  return Render;
};

export default React.memo(NodeLoop);
